var  width = 1200,
    height = 1000,
    clicked_UDP = undefined;
 
var svg = d3.select("#main_content").append("svg")
    .attr("width", width)
    .attr("height", height);

var nodes = [], links = [];

$.ajax({ url: "./udpdata/udp.json",
	async:false,
	dataType: 'json', 
	success: function(data){
	    var label = "";
		nodes = data.nodes;
		var temp_links = data.links;
		buildlinks(temp_links);
	
   },
   error: function (xhr, ajaxOptions, thrownError) {
        alert(xhr.status);
        alert(thrownError);
      }

});

//take the links that just join 
//concepts using their array position
//and build a real set of linked data containing the objects

function buildlinks(temp_links) {
   for (var x=0;x<temp_links.length;x++) {
      //remove any blank nodes...
      if (nodes[temp_links[x].source].name != "" && nodes[temp_links[x].target].name != "") {
        //remove any genes (for now)
 //       if (nodes[temp_links[x].source].type != "gene" && nodes[temp_links[x].target].type != "gene") {
          links.push({source: nodes[temp_links[x].source], target: nodes[temp_links[x].target]});
 //       }
      }
   }
}

//break the nodes list up according to type
//we have different visualizations for each type, 
//so breaking it up makes sense.
var gene_nodes = nodes.filter(function (data_item) {
  	   return data_item.type == "gene";
});

var gene_rect = svg.selectAll("rect.gene_rect").data(gene_nodes);
gene_rect.enter()
	.append('svg:rect')
	.attr('class', function(d) {
	  return 'gene_rect ' + d.name
	})
	.attr("x", 10)
	.attr('y', function(d,i) {
		return 250 + (i * 24);
	})
	.attr('width', 100)
	.attr('height', 18)
	//add an attribute to track the location of the "anchor"
	//on this rectangle.  The anchor is used for the links
	//this anchor is on the right side in the middle
	.attr('anchor', function (d) {
	    var y = this.y.baseVal.value + (this.height.baseVal.value/2);
	    return (this.x.baseVal.value + this.width.baseVal.value) + ',' + y;
	}) 
	.style("fill", "grey");

var gene_text = svg.selectAll("text.gene_text").data(gene_nodes);
gene_text.enter()
	.append("text")
	.style("fill", "white")
	.text(function(d) {
	  return d.name
	})
	.attr('class', function(d) {
	  return 'gene_text ' + d.name
	})
	.attr('x', 10)
	.attr('y', function(d,i) {
		return (250 + (i * 24)) + 15;
	});
	
var udp_nodes = nodes.filter(function (data_item) {
  	   return data_item.type == "UDP";
});

var udp_rect = svg.selectAll("rect.udp_rect").data(udp_nodes);
udp_rect.enter()
	.append('svg:rect')
	.attr('class', function(d) {
	  return 'udp_rect ' + d.name
	})
	.attr("x", 220)
	.attr('y', function(d,i) {
		return 250 + (i * 24);
	})
	.attr('width', 100)
	.attr('height', 18)

	//add an attribute to track the location of the "anchor"
	//on this rectangle.  The anchor is used for the links
	//this anchor is on the right side in the middle
	.attr('anchor', function (d) {
	    var y = this.y.baseVal.value + (this.height.baseVal.value/2);
	    return (this.x.baseVal.value + this.width.baseVal.value) + ',' + y;
	}) 

	//add an attribute to track the location of the "left_anchor"
	//on this rectangle.  The anchor is used for the links
	//this anchor is on the left side in the middle
	.attr('left_anchor', function (d) {
	    var y = this.y.baseVal.value + (this.height.baseVal.value/2);
	    return this.x.baseVal.value + ',' + y;
	}) 

	//for select event, add gene name to class
	//for udp rect's add the udp id to the class
	//for the phenotypes, add the hpo_id
	//then use these classes to select the correct items
	//.on("mouseover", function(d){selectUdp(d);})
	//.on("mouseout", function(d){deselectUdp(d);})
	.on('click', function(d) {
	   if (clicked_UDP == undefined || clicked_UDP.name != d.name) {
	     clicked_UDP = d;
	     selectUDP(d);
	   } else {
	     resetLinks(d);
	     clicked_UDP = undefined;
	   }
	})
	.on("mouseover", function(d) {
	   if (clicked_UDP == undefined) {
	     selectUDP(d);
	   }
	})
	.on("mouseout", function(d) {
	  if (clicked_UDP == undefined) {
	    resetLinks(d);
	  }
	})
	.style("fill", "black");

var udp_text = svg.selectAll("text.udp_text").data(udp_nodes);
udp_text.enter()
	.append("text")
	.style("fill", "white")
	.text(function(d) {
	   return d.name;
	})
	.attr('class', function(d) {
	  return 'udp_text';
	})
	.on('click', function(d) {
	   if (clicked_UDP == undefined || clicked_UDP.name != d.name) {
	     clicked_UDP = d;
	     selectUDP(d);
	   } else {
	     resetLinks(d);
	     clicked_UDP = undefined;
	   }
	})
	.on("mouseover", function(d) {
	   if (clicked_UDP == undefined) {
	     selectUDP(d);
	   }
	})
	.on("mouseout", function(d) {
	  if (clicked_UDP == undefined) {
	    resetLinks(d);
	  }
	})
	.attr('x', 220)
	.attr('y', function(d,i) {
		return (250 + (i * 24)) + 15;
	});
	


var phenotype_nodes = nodes.filter(function (data_item) {
  	   return data_item.type == "phenotype";
});
	
var pheno_rect = svg.selectAll("rect.pheno_rect").data(phenotype_nodes);
pheno_rect.enter()
	.append('svg:rect')
	.attr('class', function(d) {
	  return 'pheno_rect ' + d.name
	})
	.attr("x", function(d,i) {
	    return 600 + (360 * (i % 2));
	})
	.attr('y', function(d,i) {
		return Math.floor(i/2) * 16;
	})
	.attr('width', 300)
	.attr('height', 18)
	//add an attribute to track the location of the "anchor"
	//on this rectangle.  The anchor is used for the links
	//this anchor is on the left side in the middle
	.attr('anchor', function (d) {
	    var y = this.y.baseVal.value + (this.height.baseVal.value/2);
	    return this.x.baseVal.value + ',' + y;
	}) 
	/*.style("stroke", "black")
	.style("stroke-width", "1")*/

	.style("fill", "white");

var pheno_text = svg.selectAll("text.pheno_text").data(phenotype_nodes);
pheno_text.enter()
	.append("text")
	.style("fill", "black")
	.text(function(d) {
	  return d.label;
	})
	.attr('class', function(d,i) {
	  return 'pheno_text ' + d.name;
	})
	.attr("x", function(d,i) {
	    return 600 + (360 * (i % 2));
	})
	.attr('y', function(d,i) {
		return (Math.floor(i/2) * 16) + 12;
	});

var link_paths = svg.selectAll(".link").data(links);
link_paths.enter()
	.append("svg:path")
	.attr('class', function (d) {
	    return 'link ' + d.source.type + '_link' + ' ' + d.source.name + ' ' + d.target.name; 
	})
	.style("stroke-width", 2)
	.style("stroke", "lightgrey")
	.style("opacity", "0.3")
	.style("fill", "none")
	//for a bezier curve, you need the start and endpoints.
	//you also need to calculate a "control point"
	.attr("d", function(d) {
	   var src_name = d.source.name;
	   var tgt_name = d.target.name;
	   var src = svg.selectAll("rect." + src_name)[0][0];
	   var tgt = svg.selectAll("rect." + tgt_name)[0][0];
	   var src_anchor = src.attributes['anchor'].nodeValue;
	   var tgt_anchor = tgt.attributes['anchor'].nodeValue;
	   //if this is a gene swap the target and source so the curve math works.  It assumes the
	   //path is going to be drawn left to right. 
	   if (d.target.type == "gene") {
	     src_anchor =  tgt.attributes['anchor'].nodeValue;
	     tgt_anchor = src.attributes['left_anchor'].nodeValue;
	   }
	   var src_array = src_anchor.split(",");
	   var tgt_array = tgt_anchor.split(",");
	   var x_dist = Math.abs(+tgt_array[0] - +src_array[0]);
	   var y_dist = +tgt_array[1] - +src_array[1];
	   //var control_y = (+src_array[1] > +tgt_array[1]) ? +src_array[1] : +tgt_array[1];
	   var control1_y = +src_array[1];
	   var control1_x = +src_array[0] + (x_dist * 0.5);
	   var control2_y = +tgt_array[1];
	   var control2_x = +src_array[0] + (x_dist * 0.5);
	   var midpoint_x = +src_array[0] + (x_dist * 0.5);
	   var midpoint_y = +src_array[1] + (y_dist * 0.5);
	   //var control_y = (+src_array[1] + +tgt_array[1])/2;
	   //try this M 10,70 Q 50,10 50,70 Q 50,110 90,70
//	   var t_string = "M " + src.attributes['anchor'].nodeValue.replace(","," ") + " Q " + control_x + " " + control_y + " " + tgt.attributes['anchor'].nodeValue.replace(","," ");
	   var t_string = "M " + src_anchor.replace(","," ")
	       + " L " + (+src_array[0] + (x_dist * 0.33)) + " " + control1_y
	       + " Q " + control1_x + " " + control1_y + " " + midpoint_x + " " + midpoint_y
	       + " Q " + control2_x + " " + control2_y + " " + (+src_array[0] + (x_dist * 0.66)) + " " + control2_y
	       + " L " + (+src_array[0] + (x_dist * 0.66)) + " " + control2_y
	       + " " + tgt_anchor.replace(","," ");

	   return t_string;
	   
	});


function resetLinks() {

  var all_udp_rects = d3.selectAll("rect.udp_rect");
  all_udp_rects.style('fill', 'black');
  all_udp_rects.style('opacity','1.0');

  var all_gene_rects = d3.selectAll("rect.gene_rect");
  all_gene_rects.style('fill', 'grey');
  all_gene_rects.style('opacity','1.0');

  var all_gene_text = d3.selectAll("text.gene_text");
  all_gene_text.style("fill", "white");
  all_gene_text.style("font-weight", "normal");

  var all_pheno_rects = d3.selectAll("rect.pheno_rect");
  all_pheno_rects.style('fill', 'white');
  all_pheno_rects.style('opacity','1.0');
  
  var all_pheno_text = d3.selectAll("text.pheno_text");
  all_pheno_text.style("fill", "black");
  all_pheno_text.style("font-weight", "normal");

  var link_lines = d3.selectAll(".link");
  link_lines.style("stroke", "lightgrey");
  link_lines.style("stroke-width", 2);
  link_lines.style('opacity','0.3');


}

//if we want a mouseover, change this to selectUDP
function selectUDP(curr_UDP) {
//add a "None" UDP to the list.  If it is clicked, then just reset the
//colors of the links as below

   //if (curr_UDP != selected_UDP) {
     resetLinks();
  //   selected_UDP = curr_UDP;
  // }

//note: if you want to selectAll using two classes (a and b) do this: (.a.b) intersection
//the union is (.a .b)
   var udp_rect = svg.selectAll("rect." + curr_UDP.name);
   udp_rect.style("fill", "blue");
   var related_links = links.filter(function (data_item) {
  	   return data_item.source.name == curr_UDP.name;
    });
    for (var z=0;z<related_links.length;z++) {
       var pheno_text = svg.selectAll("text." + related_links[z].target.name);
       pheno_text.style("font-weight", "bold");
       pheno_text.style("fill", "blue");
       //highlight related UDPs
       var related_udp_links = links.filter(function (data_item) {
  	     return data_item.target.name == related_links[z].target.name;
       });
       for (var i=0;i<related_udp_links.length;i++) {
         var related_udp =  svg.selectAll("rect." + related_udp_links[i].source.name);
         if (related_udp_links[i].source.name != curr_UDP.name)
           related_udp.style("fill", "lightgreen");
         //select all links representing the intersection of UDP_link AND the target name.
         //ex: path.UDP_link.HP_00001234
         var related_lines =  svg.selectAll("path.UDP_link." + related_udp_links[i].target.name);
         for (var j=0;j<related_lines[0].length;j++) {
			 if (related_lines[0][j].classList.contains(curr_UDP.name)) {
			   related_lines[0][j].style.setProperty("stroke","blue");
			 } else {
			   related_lines[0][j].style.setProperty("stroke","lightgreen");
			 }
         }
         related_lines.style("opacity", "0.3");
	     related_lines.style("stroke-width", "5");


       }
    }

}
